package de.recipeminer.tools;

import org.apache.log4j.Logger;
import org.jruby.embed.ScriptingContainer;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Properties;

public class Config {
    protected String MAVEN_PROPERTY_FILE = "maven.properties";
    private String minerEnv;
    private static Logger logger = Logger.getLogger(Config.class);
    private static Config instance = new Config();
    private Properties mavenPropertiesCache = null;

    private Config() {
        minerEnv  = System.getenv("MINERENV");
        if(minerEnv == null || minerEnv.isEmpty()) {
            minerEnv = "development";
        }
    }

    public static Config getInstance() {
        return instance;
    }

    protected Properties getMavenProperties() {
        if (mavenPropertiesCache == null) {
            mavenPropertiesCache = new Properties();
            try {
                mavenPropertiesCache.load(getResourceStream(MAVEN_PROPERTY_FILE));
            } catch (IOException e) {
                String msg = String.format("An error occurred attempting to open %s:", MAVEN_PROPERTY_FILE);
                throw new RuntimeException(msg, e);
            }
        }
        return mavenPropertiesCache;
    }


    public InputStream getResourceStream(String relPath) {
        String envRelPath = Tools.joinPaths(minerEnv, relPath);
        InputStream inputStream = getClasspathResourceStream(envRelPath);
        if (inputStream == null) {
            inputStream = getClasspathResourceStream(relPath);
        }
        if (inputStream == null) {
            throw new UnableToLocateResourceException(relPath);
        }
        return inputStream;
    }

    public File getResource(String relPath) {
        String envRelPath = Tools.joinPaths(minerEnv, relPath);
        URL url = getClasspathResource(envRelPath);
        if(url == null) {
           url = getClasspathResource(relPath);
        }
        if(url == null) {
            throw new UnableToLocateResourceException(relPath);
        }
        return new File(url.getPath());
    }

    protected InputStream getClasspathResourceStream(String relPath) {
        InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(relPath);

        return inputStream;
    }

    protected URL getClasspathResource(String relPath) {
        URL url = Thread.currentThread().getContextClassLoader().getResource(relPath);

        return url;
    }

    @Deprecated
    public File getRubyResource(String relPath) {
        return callRubyResource("get_resource", relPath);
    }

    @Deprecated
    public File getRubyTestResource(String relPath) {
        return callRubyResource("get_test_resource", relPath);
    }

    @Deprecated
    private File callRubyResource(String configMethod, String path) {
        ScriptingContainer container = RubyScriptContainer.getDefaultContainer();
        Object rubyConfig = container.runScriptlet("Config");
        Object pathName = container.callMethod(rubyConfig, configMethod, path);
        String resPath = (String) container.callMethod(pathName, "to_s");
        return new File(resPath);
    }

    class UnableToLocateResourceException extends RuntimeException {
        public UnableToLocateResourceException(String resourceDescriptor) {
            super(String.format("Unable to locate resource '%s' using classloader %s.",
                    resourceDescriptor,
                    Thread.currentThread().getContextClassLoader().getClass().getName()));
        }
    }

    public static void main(String[] args) {
        File log4j = Config.getInstance().getResource("log4j.properties");
        System.out.println(log4j != null ? log4j : "NULL");

    }
}